<?php
base()->loader = new LoaderLibrary;
base()->objectName = null;

#### FUNCTIONS #################################################################
function load() { return base()->loader; }
function library($name, $alias = null) { return load()->library($name, $alias); }
function model($name = null, $alias = null) { return load()->model($name); }
function view($name, $variables = null) { load()->view($name, $variables); }
function controller($name, $alias = null) { 
	return load()->controller($name, $alias); 
}

#### LOADER LIBRARY ############################################################
class LoaderLibrary {

	private $path = array(
		'helpers' => 'includes/helpers',
		'libraries' => 'includes/libraries',
		'third-party' => 'includes/third-party',
		'models' => 'models',
		'views' => 'views',
		'controllers' => 'controllers',
	);

	#### SET PATH ##############################################################
	public function setPath($type, $path) { $this->path[$type] = $path; }

	#### GET PATH ##############################################################
	public function getPath($type) { return $this->path[$type]; }	

	#### FILE ##################################################################
	public function file($path, $variables = null) {
		if ($variables) extract($variables);
		return include($path);
	}
	
	#### OBJECT ################################################################
	public function object($name, $path, $class = null, $parent = 'class') {
		// Return if the key already exists
		if (isset($this->$parent->$name)) return $this->$parent->$name;

		// Load the object and assign it to the key
		if ($this->file($path)) {
			if (!$class) $class = $name;
			if (!isset($this->$parent)) $this->$parent = new StdClass();
			$this->$parent->$name = new $class();
			base()->lastObjectName = base()->objectName;
			base()->objectName = $name;
			base()->object = $this->$parent->$name;
			return $this->$parent->$name;
		}
	}
	
	#### HELPER ################################################################
	public function helper($name) {
		return $this->file($this->getPath('helpers').'/'.$name.'.php');
	}

	#### LIBRARY ###############################################################
	public function library($name, $alias = null) {
		return $this->object(
			($alias ? $alias : $name), 
			$this->getPath('libraries').'/'.$name.'.php', 
			$name.'Library',
			'library'
		);
	}

	#### MODEL #################################################################
	public function model($name, $alias = null) {

		// If no name was supplied use the object name
		if (!$name) $name = base()->objectName;

		// If a model file does not exist return the Model Library
		if (!file_exists(load()->getPath('models').'/'.$name.'.php')) {
			$object = clone library('model');
			if (method_exists($object, 'setTable')) $object->setTable($name);
			return $object;
		}
		// Else we have a model file
		else {
			$currentObjectName = base()->objectName;
			$object = $this->object(
				($alias ? $alias : $name),
				$this->getPath('models').'/'.$name.'.php', 
				$name.'Model', 
				'model'
			);
			if (method_exists($object, 'setTable')) $object->setTable($name);
		
			// Restore changes to objectName caused by $this->object()
			base()->objectName = $currentObjectName; 

			return $object;
		}
	}
	
	#### VIEW ##################################################################
	public function view($name, $variables = null) {
		return $this->file($this->getPath('views').'/'.$name.'.html', $variables);
	}	
	
	#### CONTROLLER ############################################################
	public function controller($name, $alias = null) {
		return $this->object(
			($alias ? $alias : $name), 
			$this->getPath('controllers').'/'.$name.'.php', 
			$name.'Controller',
			'controller'
		);
	}
}
?>